﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
using System.Drawing.Drawing2D;

namespace WiimoteControls
{
    public partial class WiimoteAccelerationBox : UserControl, IWiimoteSupported
    {
        private Wiimote _wiimote;
        private List<AccelState> _accelStates;

        private Color _colorX = Color.Red;
        private Color _colorY = Color.Green;
        private Color _colorZ = Color.Yellow;

        public WiimoteAccelerationBox()
        {
            InitializeComponent();

            BackColor = Color.Black;
            _accelStates = new List<AccelState>(500);
        }

        #region IWiimoteSupported Members

        [Browsable(false)]
        public Wiimote Wiimote
        {
            get
            {
                return _wiimote;
            }
            set
            {
                _wiimote = value;

                if (_wiimote != null)
                {
                    _wiimote.WiimoteChanged += new WiimoteChangedEventHandler(Wiimote_WiimoteChanged);
                }
            }
        }

        #endregion

        [DefaultValue(typeof(Color), "System.Drawing.Color.Black")]
        public new Color BackColor
        {
            get { return base.BackColor; }
            set { base.BackColor = value; }
        }

        [DefaultValue(typeof(Color), "System.Drawing.Color.Red")]
        public Color ColorAxisX
        {
            get { return _colorX; }
            set 
            { 
                _colorX = value;
                chkShowX.ForeColor = value;

                Invalidate();
            }
        }

        [DefaultValue(typeof(Color), "System.Drawing.Color.Green")]
        public Color ColorAxisY
        {
            get { return _colorY; }
            set 
            { 
                _colorY = value;
                chkShowY.ForeColor = value;

                Invalidate();
            }
        }

        [DefaultValue(typeof(Color), "System.Drawing.Color.Yellow")]
        public Color ColorAxisZ
        {
            get { return _colorZ; }
            set 
            { 
                _colorZ = value;
                chkShowZ.ForeColor = value;

                Invalidate();
            }
        }

        private void Wiimote_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
        {
            _accelStates.Add(args.WiimoteState.AccelState);

            if (_accelStates.Count == 500)
                _accelStates.RemoveAt(0);

            Invalidate();
        }

        private void WiimoteAccelerationBox_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            float transformY = (float)ClientSize.Height / 2F;
            float transformX = 25F;
            float multiplicatorY = 13.0F;

            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.Clear(BackColor);

            #region Draw Axis
            
            Pen penAxis = new Pen(Color.White);

            //Draws x-axis
            g.DrawLine(
                penAxis, 
                new PointF(0, transformY), 
                new PointF(ClientSize.Width, transformY));

            //Draws y-axis
            g.DrawLine(
                penAxis,
                new PointF(transformX, 0),
                new PointF(transformX, ClientSize.Height));
            
            #endregion

            Pen penXValues = new Pen(_colorX);
            Pen penYValues = new Pen(_colorY);
            Pen penZValues = new Pen(_colorZ);

            #region Draw Values
            
            float numberOfAccelStates = (float)_accelStates.Count;
            float xStep = ((float)ClientSize.Width - transformX) / numberOfAccelStates;

            for (int i = 1; i < numberOfAccelStates; i++)
            {
                float xPos = xStep * i;
                float xPosLast = xStep * (i - 1);

                float yPos = 0.0F;
                float yPosLast = 0.0F;
                //////////////////////////////

                if (chkShowX.Checked)
                {
                    yPos = _accelStates[i].X * multiplicatorY;
                    yPosLast = _accelStates[i - 1].X * multiplicatorY;

                    g.DrawLine(
                         penXValues,
                         new PointF(xPosLast + transformX, yPosLast + transformY),
                         new PointF(xPos + transformX, yPos + transformY));
                }
                //////////////////////////////

                if (chkShowY.Checked)
                {
                    yPos = _accelStates[i].Y * multiplicatorY;
                    yPosLast = _accelStates[i - 1].Y * multiplicatorY;

                    g.DrawLine(
                         penYValues,
                         new PointF(xPosLast + transformX, yPosLast + transformY),
                         new PointF(xPos + transformX, yPos + transformY));
                }
                //////////////////////////////

                if (chkShowZ.Checked)
                {
                    yPos = _accelStates[i].Z * multiplicatorY;
                    yPosLast = _accelStates[i - 1].Z * multiplicatorY;

                    g.DrawLine(
                         penZValues,
                         new PointF(xPosLast + transformX, yPosLast + transformY),
                         new PointF(xPos + transformX, yPos + transformY));
                }
            }
            
            #endregion
        }
    }
}
